import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import CustomAxiosInstance, { StatusConfig } from './instance'

// AxiosInstance 是 Axios 的子类，有 get / post / put / delete 等方法
// AxiosRequestConfig 为请求配置，详细配置见 https://www.axios-http.cn/docs/req_config
// AxiosResponse 为请求后得到的响应结果的结构

// 请求成功返回一个包含两个元素的数组(二元组)，第一个必须为 null，第二个可以是任意类型，表示用户需要的结果
type ResponseSuccess = [null, any]
// 请求失败返回一个二元组，第一个 any 用于标识错误相关信息，第二个为 null，表示无用户结果
// type ResponseFail = [any, null]
export class ResponseFail {
  message: string
  code: number
  constructor(errorResponse: any) {
    this.message = errorResponse.message
    this.code = errorResponse.code
  }
}

/**
 * 封装各个请求方法即结果处理的类
 */
class Request {
  instance: AxiosInstance

  constructor(instance: AxiosInstance) {
    this.instance = instance
  }

  static successHandler(response: AxiosResponse) {
    // const result: ResponseSuccess = [null, response]
    // return result
    return response
  }

  static failHandler(error: any) {
    return new ResponseFail(error)
  }

  async get(url: string, config?: AxiosRequestConfig) {
    // try {
    const response = await this.instance.get(url, config)
    return Request.successHandler(response)
    // } catch (error) {
    //   return Request.failHandler(error)
    // }
  }

  async post(url: string, data?: any, config?: AxiosRequestConfig) {
    // try {
    const response = await this.instance.post(url, data, config)
    return Request.successHandler(response)
    // } catch (error) {
    //   return Request.failHandler(error)
    // }
  }

  async put(url: string, data?: any, config?: AxiosRequestConfig) {
    try {
      const response = await this.instance.put(url, data, config)
      return Request.successHandler(response)
    } catch (error) {
      return Request.failHandler(error)
    }
  }

  async delete(url: string, config?: AxiosRequestConfig) {
    try {
      const response = await this.instance.delete(url, config)
      return Request.successHandler(response)
    } catch (error) {
      return Request.failHandler(error)
    }
  }
}

// Request 工厂方法
export function createRequest(axiosConfig?: AxiosRequestConfig, statusConfig?: StatusConfig) {
  const customInstance = new CustomAxiosInstance(axiosConfig, statusConfig)
  return new Request(customInstance.instance)
}

export const request = createRequest()
